Home

buildLifecycle: experimental

Introduction

Xposome is a shiny application that aims to build a repository of gene expression datasets that profile the transcriptomic response to exposure of known toxins.


Local Installation

Must have R and Rstudio installed before proceeding:

To run Xposome application locally:

  • Download the source code from GitHub repo
  • Unzip the file and navigate to shinyApps folder
  • Open app.R within that folder
  • Click Run App button to launch the application in Rstudio


Dockerize Xposome Application

Not familiar with Docker? You can download it here and check out the R Docker tutorials.

To dockerize the Xposome application:

  • Download the source code from GitHub repo
  • Unzip the file and open the terminal. Use the cd command to navigate to where the dockerfile is stored. The dockerfile is a text file that contains all of the dependences and instructions of how to run the Xposome app.
  • Run the following command to build the docker image for the Xposome application
    docker build xposome .
    To check if the image is built succesfully,
    docker images
  • Create a docker container that contains the Xposome image and publish the application on the host machine.
    docker run -d -p 3838:3838 \
      -v shinyApps/:/srv/shiny-server/ \
      -v shinyApps-log/:/var/log/shiny-server/ \
      xposome:latest
    -d is to run the container in detached mode
    -v is to mount the codebase or data files from the host directory onto the container directory <host_dir>:<container_dir>
    -p is to link the container port onto the host port and publish the application on the host domain <host_port>:<container_port>
    For more information about the syntax usage, see docker documentation

    To check if the container is built and running sucessfully,
    docker container ps
  • Once the app is up and running, you can visit the local host, http://localhost:3838 to vertify if the application is indeed hosted there.

The docker image for Xposome is also available at Docker Hub. To pull the image, just type the following command in the terminal:

docker pull montilab/xposome

Additionally, check out how to configure http and https traffics with NGINX and Docker-Compose


Data Access

The Xposome application requires several structural datasets in order for it to run smoothly. We provide API access to our data, see API Explorer.


Application Usage

There are two main parts of the Xposome application:

  • Project Page
  • Moderator Page


The Project Page

Contains a list of projects or chemical screenings that were exposed to high-throughput transcriptomics assays. Each screen provides annotation about the chemicals and cell-line samples that were used in the experiment. A detailed analysis was also done to explore gene expression set, gene set enrichment, and gene connectivity that was exposed to a panel of known carcinogens.

Below is a screenshot of our home page.



Below is a snapshot of the Adipogenicity project:



The Moderator Page

Requires access from authorized users. This restricted page only allows certain users to make changes to the existed screens or to upload new screens onto the Project Page.

The default login credentials are set as:

  Username: Xposome
  Password: Xposome

Lastly, check out the documentation of how to reset password if users forgot their login credentials using Send Emails with Postfix

License

Developers

NGINX and Docker-Compose

NGINX & Docker-Compose

NGINX - An open source web server and reverse proxy technology used for hosting websites and applications

Docker-compose - A technology for enabling docker containers to communicate to each other

In this post, I will go over steps of how to create an encrypt (https) traffic that allows users to interact with the Xposome application that is published through a docker container. To achieve that, we need both NGINX and docker-compose.

Here are seven steps to set-up NGINX and docker-compose:

  1. Install docker-compose
  2. Build a NGINX image from Docker Hub without installing NGINX software
  3. Dockerize the Xposome application locally or pull the image from Docker Hub
  4. Configure NGINX configuration files
  5. Create a docker-compose.yml file
  6. Run the docker-compose.yml file
  7. Check to see if the application is running on https


Step 1: Install docker-compose

See how to install Docker-compose here

To check if docker-compose is installed,

docker-compose --version

Step 2: Build a docker image for NGINX

An image for NGINX can be found at Docker Hub. You can pull this image without the need to install the NGINX software locally.

docker pull nginx:latest 

To check if the image is built successfully

docker images

Also see this link on how to use the image

Step 3: Dockerize the Xposome application locally or pull the image from Docker Hub

Check out this post here for more details

Step 4: Configure NGINX configuration files

Once the images for NGINX and Xposome are build successfully, we can start configure the NGINX configuration files. There are two configuration files for NGINX, nginx.conf and default.conf.template files.

The nginx.conf file contains the standard configuration for NGINX. Unless you know how to add directives specific to a configuration file, otherwise, I do not recommend making any changes to this file.

The default.conf.templat file contains HTTP configuration that allows NGINX to direct any encrypt (https) or unencrypt (http) traffics to the application that is published on a specific port on the host machine.

How NGINX talks to Docker

With NGINX,
nginx → listens on → port 80 (http) and 443 (https) 

With Docker,
Docker → listens on → port 80/443/8080/3838/8000/… 

With SHINY
Shiny → listens on localhost → port 3838/8787/4848/… 

In other words, when we run a docker container, we basically expose our application through a port that is viewable on a Shiny's localhost (for example: port 3838). Docker listens to this port and publish the application to a specific port on the host machine (for example: port 7856). Therefore, when we navigate to port 7856 on the host domain (for example http://[domain_name/ip address]:7856), we will see that the shiny app is hosted there.

Nevertheless, we probably do not want to direct our users to the application via a port link. Thus, we can use the NGINX configuration files to create an alias location for the application (for example https://[domain_name/ip address]/Xposome/). Hence, when a user is navigated to that specific address on the host domain, NGINX will transfer that traffic to the port 7856 of where the application was originally published on. Furthermore, NGINX will encrypt that traffic with a https protocol. As the result, NGINX is served as a reverse proxy for hosting our applications.

Here is a snapshot of how the http configuration file looks like:

  server {
      listen       80;          
      server_name  montilab.bu.edu;  #ip address or domain name
      server_tokens off;

      # Load configuration files for the default server block.
      include /etc/nginx/default.d/*.conf;

      # Specific the location for the xposome app
      location /Xposome/ {
        rewrite ^/Xposome/(.*)$ /$1 break;
        proxy_pass http://montilab.bu.edu:7856/; 

        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 20d;
        proxy_buffering off;
      }
  }

Step 5: Create a docker-compose.yml file

Once we had configured NGINX as a reverse proxy for our application, we can create a docker-compose.yml file that comprises of all the containers that we want to communicate with NGINX container.

To enable communication between containers, in the docker-compose file, we must create a service to run the NGINX container and a service to run the Xposome container. Under each service, we need to specify a list of instructions of how the container can be built, for instance, what image is used to build the container, what do we want to name the container, what port is used to expose the shiny app to Docker, and what port is used to publish the app on the host machine, etc.

After we had defined all of the key components of how the containers can be built, in the NGINX configuration files, we need to make sure that the host port matches the port that NGINX redirects the encrypt traffics to the application.

Here is a snapshot of the docker-compose.yml file:

version: '3'

services:
  nginx:
    image: nginx:latest         #name of the image
    container_name: nginx       #name of the container you want to build
    restart: always             #allow the connection to restart if it gets disconnected
    ports:
      - 80:80   #specify the unencrypt port
      - 443:443 #specify the encrypt port but will need ssl later
    volumes:
      - /home/docker/nginx/nginx.conf:/etc/nginx/nginx.conf #connect the host configuration files to docker config files
      - /home/docker/nginx/conf.d:/etc/nginx/templates #connect the host configuration files to docker config files
    command: [nginx-debug, '-g', 'daemon off;']

  xposome:
    image: montilab/xposome:latest  #name of the docker image
    container_name: xposome         #name of the container
    restart: always
    ports:
      - 7856:3838                   #port where the application is published on   
    volumes:
      - /home/xposome/shinyApps/:/srv/shiny-server/           #location to the codebse or data files
      - /home/xposome/shinyApps-log/:/var/log/shiny-server/   #location to store log information from the shiny app

Step 6: Run the docker-compose file

After we have the docker-compose file and NGINX configuration files all set up, we can cd to where docker-compose.yml is located and run the following command to fire up all the containers that are defined within the docker-compose file.

docker-compose up -d

-d is used to run docker compose in detach mode

Step 7: Check to make sure the application is running on https

Navigate to the alias domain for the application (for example https://montilab.bu.edu/Xposome/) and see if the application is indeed hosted there.

License

Developers

Send Emails with Postfix

Send Emails with Postfix

Postfix - A popular open-source Mail Transfer Agent (MTA) that can be used to route and deliver emails on a Linux system

Docker - A software platform that allows developers to build, test, deploy, and run applications using containers

In this post, I will go over steps of how to send emails from a docker container through Postfix installed on the host machine. In my previous posts, I went over how to dockerize the Xposome application. The Xposome application has two parts: the Project Page and the Moderator Page. In the Moderator Page, we have an option that allow users to retrieve their passwords if they forgot their login credentials.

Here are five steps to set-up Postfix and send new passwords to users if they forgot their login credentials:

  1. Install Postfix
  2. Dockerize the Xposome application locally or pull the image from Docker Hub
  3. Configure Postfix to listen to requests from docker container
  4. Write an email to test the Postfix Mail Server
  5. Check to see if the email is sent correctly

Step 1: Install Postfix

Depending on your Operating System, for mine, I have CentOS 8 server. Therefore, I will use this documenation on how to install and configure postfix mail server on CentOS 8. You can also see this link to install and configure Postfix on Ubuntu 16.04.

Step 2: Dockerize the Xposome application locally or pull the image from Docker Hub

See my previous post here

Step 3: Configure Postfix to listen to requests from docker container

After Postfix is installed, the main configuration files is stored at /etc/postfix/main.cf.

To configure Postfix to listen to requests from docker container, there is something called docker bridge (docker0) which acts as a bridge between the ethernet port and the docker container so that data can go back and forth. Hence, we want Postfix to listen on the docker0 interface. To do that, type ifconfig on your host system to find out the bridge address and set your Postfix to listen on it.

As you can see in the image above, the IP address is 172.17.0.1

In the Postfix configuration file (/etc/postfix/main.cf), set

inet_interfaces = 172.17.0.1

While you are there, add your actual docker container ip address to mynetworks

mynetworks = 172.17.0.5

172.17.0.5 is the private IP address of my docker container from which I use to send emails.

You can find the IP address for your docker container by

docker inspect [container_id/container_name]

For example,

docker inspect montilab/xposome

Step 4: Write an email to test the Postfix Mail Server

Here is an email function that sends a temporary password to users who forgot their login credentials:

sendpassword <- function(from_sender="rchau88@bu.edu", to_recipient="lilychau999@gmail.com", recipient_first="Reina", recipient_last="Chau", recipient_account="Reina", tmp_pwd){

  recipient=paste(recipient_first, recipient_last)

  msg <- mime_part(
    paste0(
      '<!DOCTYPE>',
      '<html>',
      '<head>',
      '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>',
      '<meta name="viewport" content="width=device-width, initial-scale=1.0"/>',
      '<title>HTML MESSAGE</title>',
      '<style type="text/css">',
      '</style>',
      '</head>',
      '<body>',
      '<p>Hi <strong>', recipient_first, ',</strong></p>',
      '<p>The password for your Xposome account has changed.</p>',
      '<p></p>',
      '<p>Username: <strong>', recipient_account, '</strong></p>',
      '<p>Temporary password: <strong>', tmp_pwd, '</strong></p>',
      '<br>',
      '<p>Best,</p>',
      '<p>Montilab Team</p>',
      '</body>',
      '</html>' 
    )
  )

  ## Override content type.
  msg[["headers"]][["Content-Type"]] <- "text/html"

  from <- paste0("\"Montilab Team\"<", from_sender, ">")
  to <- paste0("\"", recipient, "\"<", to_recipient, ">", collapse="")
  subject <- "Temporary password for Xposome"
  body <- list(msg)
  sendmail(from, to, subject, body, control=list(smtpServer="smtp.bu.edu", smtpPort="25"))

}

On the shiny interface, when a user clicks the forgot password?, a modal dialog will pop up. After he/she provided the user account information and click the submit button, a new temporary password will be send to his/her email.

observeEvent(input$FG_Button, {

  Firstname=trimws(input$FG_Firstname);
  Lastname=trimws(input$FG_Lastname);
  Username=trimws(input$FG_Username);

  login_dat <- read.csv(paste0("data/User_Login_List.csv"), header = TRUE, stringsAsFactors = FALSE)

  if(Firstname=="" | Lastname=="" | Username==""){

    forgotpasswordwarningmsg("Please fill in the required (*) fields.")

  }else{

    row <- which(login_dat$Username == Username)

    if(length(row) > 0){

      tmp_pwd <- password(n = 10, numbers = TRUE, case = TRUE, special = c("?", "!", "&", "%", "$"))
      login_dat$Password[row[1]] <- sodium::password_store(as.character(tmp_pwd))
      sendpassword(
        from_sender="rchau88@bu.edu",
        to_recipient="lilychau999@gmail.com", 
        recipient_first=Firstname, 
        recipient_last=Lastname, 
        recipient_account=Username, 
        tmp_pwd=tmp_pwd
      )
      write.csv(login_dat, paste0("data/User_Login_List.csv"), row.names = FALSE)
      forgotpasswordwarningmsg("Thank you for your submission! A temporary password has been sent to your email.")

    }else{

      forgotpasswordwarningmsg("This username does not exist in our database. Please enter another username.")

    }

  }
})

Here a snapshoot of the Xposome interface:

Step 5: Check to see if the email is sent correctly

if you are using the same email format that I have structured, then you should receive an email similar to this one.

License

Developers

API Explorer

API EXPLORER

The API Explorer provides documentation on how users can retrieve data from the Xposome application and create their next project. All successful responses are returned in JSON. Only queries that respond with a 200 response code is considered successful.

Here are standard HTTP codes you will find in the “Status” element of the response body.

Status Code Description
200 OK Standard HTTP successful response
404 Bad Request or Source Not Found. Standard HTTP invalid request response
500 Internal Server Error There was an unexpected error on our server. If you see this error, please help us notify the issue on on our GitHub page


There are four data sources that are currently returned from the API.

Data Description Return
Projects a list of projects in the GeneHive Database. See here on how we define projects on our web page list
Chemicals a list of chemicals available in a specific project list
Statistics a summary statistics for a specific chemical within a particular project. The statistics are calculated based on its gene expression, gene set enrichment and gene connectivity data frame
Datasets a list of data sources for the Xposome projects such as profile and chemical annotation, expression set, gene set enrichment and connectivity set data frame


Below are a list of R packages and GET requests in R to retrieve data from the Xposome projects. However, one can use Python or other programs to implement the REST API calls.


# R packages required for API calls
library(jsonlite)
library(httr)

Projects

/projects Return a list of projects available in the GeneHive database


Implementation

https://montilab.bu.edu/Xposome-API/projects?orderby=asc


Parameter Value Description Data Type
orderby asc (default) or desc Sort options string


Example in R


# url for local testing
url <- "https://montilab.bu.edu/Xposome-API/projects?orderby=asc"

# Send GET Request to API
res <- GET(url = url, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


### If GET request is successful, return the results
if(test_request == "pass"){

  projects <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(projects))

}

Chemicals

/chemicals Return a list of chemicals available in a specific project


Implementation

https://montilab.bu.edu/Xposome-API/chemicals?project=MCF10A


Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string


Example in R


project_name = "MCF10A"

# url for local testing
url0 <- paste0("https://montilab.bu.edu/Xposome-API/chemicals?project=", project_name)

# Send GET Request to API
res <- GET(url = url0, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  chemicals <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(chemicals))

}

Statistics

/gene_expression Return a collection of differential expressed genes that exposed to a known toxin


Implementation

https://montilab.bu.edu/Xposome-API/gene_expression?project=MCF10A&chemical_id=1,2-Dibromo-3-chloropropane&summarize.func=median&landmark=TRUE&do.markers=TRUE&do.scorecutoff=TRUE


Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string
chemical_id 1,2-Dibromo-3-chloropropane or … Name of the chemicals or CAS ids of a chemical in a specific project string
summarize.func median (default) or mean/min/max/Q1/Q3 Name of the summarize functions string
landmark TRUE or FALSE (default) Whether to include landmark genes boolean
do.nmarkers TRUE (default) or FALSE Whether to filter by the number of landmark genes (ranging from 1 to 1000) boolean
do.scorecutoff TRUE (default) or FALSE Whether to filter by the z-scores (cutoff from -2 to 2) boolean


Example in R


chemical_id = chemicals[4]

# url for local testing
url1 <- paste0("https://montilab.bu.edu/Xposome-API/gene_expression?project=", project_name, "&chemical_id=", chemical_id, "&summarize.func=median&landmark=TRUE&do.markers=TRUE&do.scorecutoff=TRUE")

# Send GET Request to API
res <- GET(url = url1, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  gene_expression_stat <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(gene_expression_stat[1:5, 1:5]))

}

/gs_enrichment Return a collection of gene set enrichment that was exposed to a given drug


Implementation

https://montilab.bu.edu/Xposome-API/gs_enrichment?project=MCF10A&chemical_id=1,2-Dibromo-3-chloropropane&geneset=Hallmark&gsva=gsva&summarize.func=median


Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string
chemical_id 1,2-Dibromo-3-chloropropane or … Name of the chemicals or CAS ids of a chemical in a specific project string
geneset Hallmark (default) or C2 or NURSA Collection of the gene set enrichment string
gsva gsva (default) Method of the gene set enrichment analysis string
summarize.func median (default) or mean/min/max/Q1/Q3 Name of the summarize functions string


Example in R


# url for local testing
url2 <- paste0("https://montilab.bu.edu/Xposome-API/gs_enrichment?project=", project_name, "&chemical_id=", chemical_id, "&geneset=Hallmark&gsva=gsva&summarize.func=median")

# Send GET Request to API
res <- GET(url = url2, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  gs_enrichment_stat <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(gs_enrichment_stat[1:5, 1:5]))

}

/connectivity Return a collection of gene connectivity that are linked to exposure of a known chemical


Implementation

https://montilab.bu.edu/Xposome-API/connectivity?project=MCF10A&chemical_id=1,2-Dibromo-3-chloropropane&connectivity_classes=pcl&summarize.func=median


Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string
chemical_id 1,2-Dibromo-3-chloropropane or … Name of the chemicals or CAS ids of a chemical in a specific project string
connectivity_classes pcl (Perturbagen Classes, default) or pert (Perturbagens) Name of the connectivity classes string
summarize.func median (default) or mean/min/max/Q1/Q3 Name of the summarize functions string


Example in R


# url for local testing
url3 <- paste0("https://montilab.bu.edu/Xposome-API/connectivity?project=", project_name, "&chemical_id=", chemical_id, "&connectivity_classes=pcl&summarize.func=median")

# Send GET Request to API
res <- GET(url = url3, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  connectivity_stat <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(connectivity_stat[1:5, 1:5]))

}

Datasets

/profile_annotation Return the profile annotation of a specific project


Implementation

https://montilab.bu.edu/Xposome-API/profile_annotation?project=MCF10A


Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string


Example in R


# url for local testing
url4 <- paste0("https://montilab.bu.edu/Xposome-API/profile_annotation?project=", project_name)

# Send GET Request to API
res <- GET(url = url4, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  profile_annotation <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(profile_annotation[1:5, 1:5]))

}

/chemical_annotation Return the chemical annotation of of a specific project


Implementation

https://montilab.bu.edu/Xposome-API/chemical_annotation?project=MCF10A


Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string


Example in R


# url for local testing
url5 <- paste0("https://montilab.bu.edu/Xposome-API/chemical_annotation?project=", project_name)

# Send GET Request to API
res <- GET(url = url5, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  chemical_annotation <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(chemical_annotation[1:5, 1:5]))

}

/expression_set Return the gene expression dataset of a specific project


Implementation

https://montilab.bu.edu/Xposome-API/expression_set?project=MCF10A


Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string


Example in R


# url for local testing
url6 <- paste0("https://montilab.bu.edu/Xposome-API/expression_set?project=", project_name)

# Send GET Request to API
res <- GET(url = url6, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  expression_set <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(expression_set[1:5, 1:5]))

}

/enrichment_set Return the enrichment dataset of a specific project


Implementation

https://montilab.bu.edu/Xposome-API/enrichment_set?project=MCF10A&geneset=Hallmark&gsva=gsva

Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string
geneset Hallmark (default) or C2 or NURSA Collection of the gene set enrichment string
gsva gsva (default) Method of gene set enrichment analysis string


Example in R


# url for local testing
url7 <- paste0("https://montilab.bu.edu/Xposome-API/enrichment_set?project=", project_name, "&geneset=Hallmark&gsva=gsva")

# Send GET Request to API
res <- GET(url = url7, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  enrichment_set <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(enrichment_set[1:5, 1:5]))

}

/connectivity_set Return the connectivity dataset of a specific project


Implementation

https://montilab.bu.edu/Xposome-API/connectivity_set?project=MCF10A&connectivity_classes=pcl

Parameter Value Description Data Type
project MCF10A or HEPG2 or … Name of the projects string
connectivity_classes pcl (Perturbagen Classes, default) or pert (Perturbagens) Name of the connectivity classes string

Example in R


# url for local testing
url8 <- paste0("https://montilab.bu.edu/Xposome-API/connectivity_map?project=", project_name, "&connectivity_classes=pcl")

# Send GET Request to API
res <- GET(url = url8, encode = 'json')

# Check the status of GET request 
test_request <- tryCatch({

  stop_for_status(res)

  "pass"

}, error = function(e) {

  "fail"

})

Output


# If GET request is successful, return the results
if(test_request == "pass"){

  connectivity_map <- fromJSON(fromJSON(rawToChar(res$content)))
  print(head(connectivity_map[1:5, 1:5]))

}

License

Developers